package game.module.mj.processor;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import game.common.PlayingRoleMsgProcessor;
import game.entity.PlayingRole;
import game.module.mj.MjConstants;
import game.module.mj.bean.MjRound;
import game.module.mj.logic.MjDataManager;
import game.module.mj.logic.MjEstimateUserRespondHelper;
import game.module.mj.logic.MjLogic;
import game.session.SessionManager;
import lion.common.MsgCodeAnn;
import lion.netty4.message.MyRequestMessage;
import lion.netty4.message.RequestMessageRaw;
import lion.netty4.message.RequestProtoMessage;
import lua.LuaMessageLogin.S2ErrorCode;
import lua.LuaMessageMj.C2SMJChupai;
import lua.LuaMessageMj.PushMJChupai;
import lua.LuaMessageMj.S2CMJChupai;

@MsgCodeAnn(msgcode = C2SMJChupai.id, accessLimit = 500)
public class MjChuPaiProcessor extends PlayingRoleMsgProcessor {

	private static Logger logger = LoggerFactory.getLogger(MjChuPaiProcessor.class);

	@Override
	public void process(PlayingRole playingRole, RequestMessageRaw request) throws Exception {
		
		long startMili = System.currentTimeMillis();
		C2SMJChupai reqMsg = C2SMJChupai.parse(request);
		byte cbCardData = reqMsg.pai;
		int playerId = playingRole.getId();
		
		S2CMJChupai respMsg = new S2CMJChupai((short) 0,(short)0);
		// 当前是否是我的回合
		final MjRound mjround = MjDataManager.getInstance().getMjRoom(playerId);
		int m_wCurrentUser = mjround.getPlayerIds().indexOf(playerId);
		//int wChairID = mjround.getChupai_index(); // 当前出牌的下标
		int wChairID = mjround.getM_wCurrentUser();
		byte cardIndex[][] = mjround.getCardIndex();
		boolean [] CanFen = mjround.getGenFeng();
		byte god_card = mjround.getGod_card();
		assert (wChairID == m_wCurrentUser);
		assert (MjLogic.IsValidCard(cbCardData) == true);
		if (wChairID !=m_wCurrentUser) {
			respMsg.is_success = 1;// 当前不是我的回合
			playingRole.writeAndFlush(respMsg.build(playingRole.alloc()));
			return;
		}
//		S2ErrorCode respMsg = new S2ErrorCode(203);
//		playingRole.writeAndFlush(respMsg.build(playingRole.alloc()));
//		return;
		// 是否我的手牌
		
		// byte[] mycard = mjround.getCards()[m_wCurrentUser];
		if (MjLogic.IsValidCard(cbCardData) == false) {
			respMsg.is_success = 3; // 牌的信息有误
			playingRole.writeAndFlush(respMsg.build(playingRole.alloc()));
			return;
		}
		if(!GuardFeng(cbCardData,(byte)m_wCurrentUser,CanFen,god_card,cardIndex[wChairID])) {
    		logger.info("cbCardData ={}, CanFen[] = {}",cbCardData,CanFen[m_wCurrentUser]);
    		logger.info("shoupai={}",cardIndex[wChairID]);
    		respMsg.is_success = 3;// 跟大牌
			playingRole.writeAndFlush(respMsg.build(playingRole.alloc()));
    		return ;
    	}
		setFollowFeng((byte)m_wCurrentUser,mjround,cbCardData);
		
		if (MjLogic.RemoveCard(cardIndex[wChairID], cbCardData) == false) {
			logger.info("failed remove cbCardData ={},",cbCardData);
			S2ErrorCode resp = new S2ErrorCode(501); //扣除手牌失败
			playingRole.writeAndFlush(resp.build(playingRole.alloc()));
			assert (false);
			return;
		}
		List<Byte> pushcard = mjround.getPushed_card().get(m_wCurrentUser);
		logger.info("out cards={}",pushcard);
		pushcard.add(cbCardData);//玩家出过的牌
		// 设置变量
		byte[] m_cbUserAction = mjround.getM_cbUserAction();
		byte[] m_cbPerformAction = mjround.getM_cbPerformAction();
		boolean[] m_bTianDiHu = mjround.getM_bTianDiHu();
		mjround.setM_bSendStatus(true);
		mjround.setM_bGangStatus(false);
		m_cbUserAction[wChairID] = MjConstants.WIK_NULL;
		m_cbPerformAction[wChairID] = MjConstants.WIK_NULL;
		m_bTianDiHu[wChairID] = true;

		
        //游金、双游、三游判断
     //   List<TagAnalyseItem> AnalyseItem = mjround.getAnalyseItemArray();
        	
      
		// 出牌记录
		mjround.setM_cbOutCardData(cbCardData);
		mjround.setM_wOutCardUser(wChairID); // 记录出牌玩家 和打出的手牌
		
		List<Byte> singCardEye = mjround.getSingCardEye().get(m_wCurrentUser);
    	List<Byte> doubleCardEye = mjround.getDoubleCardEye().get(m_wCurrentUser);
		boolean[] singlegold = mjround.getSingGold();
		boolean [] doublegold = mjround.getDoubleGold();
		boolean [] threegold = mjround.getThreeGold();
	//	int a = 0;
		if(threegold[m_wCurrentUser] == true) //三游状态继续出牌
			threegold[m_wCurrentUser] = false;
		if(doublegold[m_wCurrentUser] == true) { //双游状态继续出牌
			if(cbCardData == mjround.getGod_card())
				threegold[m_wCurrentUser] = true;//三游
			doublegold[m_wCurrentUser] = false;//双游
		}
		if(singlegold[m_wCurrentUser] == true) {//单游状态继续出牌
			singlegold[m_wCurrentUser] = false;
		}
		
		
		if(!singCardEye.isEmpty()) {
			if(singCardEye.contains(cbCardData)) //打出对子中非金牌
				singlegold[m_wCurrentUser] = true;
//			if(cbCardData == singCardEye[m_wCurrentUser])
//				singlegold[m_wCurrentUser] = true; //打出对子中非金牌
//			singCardEye[m_wCurrentUser] = 0;
		}
		if(!doubleCardEye.isEmpty()) {
			if(doubleCardEye.contains(cbCardData))
				doublegold[m_wCurrentUser] = true; //打出金牌
//			if(cbCardData == doubleCardEye[m_wCurrentUser])
//				doublegold[m_wCurrentUser] = true; //打出金牌
//			doubleCardEye[m_wCurrentUser] = 0;
		}
		if(doublegold[m_wCurrentUser]||singlegold[m_wCurrentUser]||threegold[m_wCurrentUser])
			respMsg.is_glod = 1;
		else
			respMsg.is_glod = 0;
		playingRole.writeAndFlush(respMsg.build(playingRole.alloc()));//告诉成功
		
		PushMJChupai pushMsg = new PushMJChupai();
		pushMsg.chupai_player_index = (short) m_wCurrentUser;
		pushMsg.pai = cbCardData;
		List<Integer> playerIds = mjround.getPlayerIds();
		for (Integer aPlayerId : playerIds) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);
			if (pr != null && pr.isChannelActive()) {
				pr.writeAndFlush(pushMsg.build(pr.alloc()));
				// 推送关于出牌的信息
			}
		}
		byte cbCardCount = MjLogic.GetCardCount(cardIndex[m_wCurrentUser]);
		logger.info("mj chu pai playerid={},pai={},Cards_num={}",playerId,pushMsg.pai,cbCardCount);
	//	logger.info("mj chu pai,playerId={},pai={}", playerId, cardIndex[wChairID]);
	//	byte cbCardData1[] = new byte[17];
	//	MjLogic.SwitchToCardData( cardIndex[wChairID], cbCardData1);
	//	logger.info("mj chu pai,pai={}", cbCardData1 );
    	if (mjround.getRemain_card().size() <= 16) {
    		MjLogic.OnEventGameConclude(true,mjround);
    		return ; //游戏结束
		}

    	
		
		m_wCurrentUser = m_wCurrentUser + 1;
		if(m_wCurrentUser>=4)
			m_wCurrentUser=0;
		mjround.setM_wCurrentUser(m_wCurrentUser);
		boolean[] m_bEnjoinChiHu = mjround.getM_bEnjoinChiHu();
		if(cbCardData == mjround.getGod_card()) {//金牌打出
		    for(int m = 0;m<m_bEnjoinChiHu.length;m++) {
		    	if(m==m_wCurrentUser)
		    		continue;
		    	m_bEnjoinChiHu[m] = true;
		    }
		}
		if(m_bEnjoinChiHu[m_wCurrentUser]==true) {
			m_bEnjoinChiHu[m_wCurrentUser] = false;
		}
		//logger.info("chupai={}",cbCardData);
		for(byte[] aplayer:cardIndex ) {
			if(aplayer[MjLogic.SwitchToCardIndex(mjround.getGod_card())]>=1) {
				MjEstimateUserRespondHelper.getInstance().analycardHelp((byte) wChairID, cbCardData, MjConstants.EstimatKind_OutCard, mjround,m_wCurrentUser);
				return;
			}
		}
		boolean bAroseAction = MjLogic.EstimateUserRespond(wChairID, cbCardData,MjConstants.EstimatKind_OutCard, mjround);
		mjround.setM_wResumeUser(m_wCurrentUser);
		if (bAroseAction == false) {
		//	logger.info("here={}",cbCardData);
			MjLogic.DispatchCardData(m_wCurrentUser, true, mjround);
		}
		//Date over = new Date(); 
		logger.info("cost time = {}ms",System.currentTimeMillis()-startMili);
	}

	/*
	 * 相应判断，chupai_index：出牌玩家的下标，cbCenterCard：玩家打出的牌， EstimatKind：用于效验出牌的类型，
	 * 1表示出牌的效验，2表示杠牌的效验
	 * 
	 */
	public void setFollowFeng(byte CurrentUser,MjRound mjrond,byte carddata) {
		
		byte CardIndex = MjLogic.SwitchToCardIndex(carddata);
		byte m_cbMagicIndex = MjLogic.SwitchToCardIndex(mjrond.getGod_card()); //金牌下标
		byte CardsIndex[][] = mjrond.getCardIndex();
		boolean[] CanFen = mjrond.getGenFeng();
		if(CanFen[CurrentUser])
		    CanFen[CurrentUser] = false;
		if(CardIndex < 27) 
			return ;//没有出风牌
		if(CardIndex == 33 && m_cbMagicIndex<27 )
			return ; //出的是假金牌所以，结束了
		//玩家打出了大牌	
		for(byte i=0;i<4;i++) {
			if(i == CurrentUser)
				continue;		
			CanFen[i] = true;//用户需要跟着打风牌
				
			}
	}
	public boolean GuardFeng(byte carddata,byte currentUser,final boolean[] canFeng ,byte godCard,final byte cardindex[]) {
		byte cardIndex = MjLogic.SwitchToCardIndex(carddata);
		byte m_cbMagicIndex = MjLogic.SwitchToCardIndex(godCard);
		if (canFeng[currentUser] == false) // 不需要跟打打牌
			return true;
		boolean Exit_Card = false;
		if (m_cbMagicIndex >= 27) {// 金牌是风牌的时候
			for (byte i = 27; i <= 33; i++) {
				if(i == m_cbMagicIndex)
					continue;
				if (cardindex[i] == 1) {
					Exit_Card = true;// 找到一个单个的分需要打出
					break;
				}
			}
		} else {
			for (byte i = 27; i < 33; i++) { // 金牌不是风，白板不属于风牌
				if (cardindex[i] == 1) {
					Exit_Card = true;// 找到一个单个的分需要打出
					break;
				}
			}
		}
		//存在可出大牌
		if (Exit_Card) {
			if(cardIndex<27||(m_cbMagicIndex<27 && cardIndex== 33))
		    	return false;
			else
				return true;
		}
		else {
			return true;
		}

	} 
	
	public void ZeroMemory(byte[] array) {
		for (int i = 0; i < array.length; i++) {
			array[i] = 0;
		}
	}

	public void ZeroMemory(boolean[] array) {
		for (int i = 0; i < array.length; i++) {
			array[i] = false;
		}
	}

	@Override
	public void processProto(PlayingRole playingRole, RequestProtoMessage request) throws Exception {
		
	}

	@Override
	public void processWebsocket(PlayingRole playingRole, MyRequestMessage request) throws Exception {
		

	}

}
